"""
写一个函数 StrToInt，实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。
首先，该函数会根据需要丢弃无用的开头空格字符，直到寻找到第一个非空格的字符为止。
当我们寻找到的第一个非空字符为正或者负号时，则将该符号与之后面尽可能多的连续数字组合起来，
作为该整数的正负号；假如第一个非空字符是数字，则直接将其与之后连续的数字字符组合起来，形成整数。
该字符串除了有效的整数部分之后也可能会存在多余的字符，这些字符可以被忽略，它们对于函数不应该造成影响。
注意：假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时，则你的函数不需要进行转换。
在任何情况下，若函数不能进行有效的转换时，请返回 0。
说明：
    假设我们的环境只能存储 32 位大小的有符号整数，那么其数值范围为[−231, 231− 1]。
    如果数值超过这个范围，请返回 INT_MAX (231− 1) 或INT_MIN (−231) 。
示例1:
    输入: "42"
    输出: 42
示例2:
    输入: "   -42"
    输出: -42
    解释: 第一个非空白字符为 '-', 它是一个负号。
        我们尽可能将负号与后面所有连续出现的数字组合起来，最后得到 -42 。
示例3:
    输入: "4193 with words"
    输出: 4193
    解释: 转换截止于数字 '3' ，因为它的下一个字符不为数字。
示例4:
    输入: "words and 987"
    输出: 0
    解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
         因此无法执行有效的转换。
示例5:
    输入: "-91283472332"
    输出: -2147483648
    解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
        因此返回 INT_MIN (−231) 。
链接：https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof
"""


class Solution:
    def strToInt(self, str: str) -> int:
        """
        题目要求返回的数值范围应在 [-2^{31}, 2^{31} - 1]，因此需要考虑数字越界问题。
        而由于题目指出 环境只能存储 32 位大小的有符号整数 ，
        因此判断数字越界时，要始终保持 resres 在 int 类型的取值范围内。

        在每轮数字拼接前，判断 res在此轮拼接后是否超过 2147483647，若超过则加上符号位直接返回。
        设数字拼接边界 bndry = 2147483647 // 10 = 214748364 ，则以下两种情况越界：

        res>bndry           情况一：执行拼接10×res≥2147483650越界
        res=bndry,x>7       情况二：拼接后是2147483648或2147483649越界
        """
        res, i, sign, length = 0, 0, 1, len(str)
        int_max, int_min, bndry = 2 ** 31 - 1, -2 ** 31, 2 ** 31 // 10
        if not str:
            return 0  # 空字符串，提前返回
        while str[i] == ' ':
            i += 1
            if i == length:
                return 0  # 字符串全为空格，提前返回
        if str[i] == '-':
            sign = -1
        if str[i] in '+-':
            i += 1
        for c in str[i:]:
            if not '0' <= c <= '9':
                break
            if res > bndry or res == bndry and c > '7':
                if sign == 1:
                    return int_max
                else:
                    return int_min
            res = 10 * res + ord(c) - ord('0')
        return sign * res


if __name__ == "__main__":
    """
    输入: "42"
    输出: 42
    """
    A = Solution()
    s = "    42"
    s1 = "-91283472332"
    s2 = "4193 with words"
    s3 = "words and 987"
    print('s', A.strToInt(s))
    print('s1', A.strToInt(s1))
    print('s2', A.strToInt(s2))
    print('s3', A.strToInt(s3))
